package com.refusea.train.domain.tx.impl

import com.refusea.train.domain.entity.LessonConfirmed
import com.refusea.train.domain.entity.LessonSchedule
import com.refusea.train.domain.ex.BizEx
import com.refusea.train.domain.tx.LessonScheduleTx
import com.refusea.train.mapper.ClassGroupMapper
import com.refusea.train.mapper.LessonConfirmedMapper
import com.refusea.train.mapper.LessonScheduleMapper
import com.refusea.train.mapper.OrderMapper
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author Zhang Yan 2024/4/16
 **/
@Service("lessonScheduleTx")
@Transactional
class LessonScheduleTxImpl(
    private val lessonScheduleMapper: LessonScheduleMapper,
    private val lessonConfirmedMapper: LessonConfirmedMapper,
    private val orderMapper: OrderMapper,
    private val classGroupMapper: ClassGroupMapper,
) : LessonScheduleTx {

    override fun save(list: List<LessonSchedule>, incs: Map<Int, Int>) {
        lessonScheduleMapper.deleteUnpublished(list[0].classGroupId)
        lessonScheduleMapper.schedule(list)

        // update class group next lesson number
        incs.forEach { (key, value) ->
            if (classGroupMapper.incNextLessonNumber(key, value) != 1) {
                throw BizEx.of("更新班级下一课时数失败")
            }
        }
    }

    override fun confirm(list: List<LessonConfirmed>, incs: Map<Int, Int>) {
        if (lessonConfirmedMapper.inserts(list) != list.size) {
            throw BizEx.of("插入课程核销记录失败")
        }

        if (lessonScheduleMapper.markConfirmed(list) != list.size) {
            throw BizEx.of("更新课程安排核销状态失败")
        }

        list.filter { it.lessonNumber == it.course!!.lessonCount }.forEach {
            // update order study-status if all lessons completed
            if (orderMapper.completed(it.schoolId, it.courseId, it.studentIds!!) != it.studentIds!!.size) {
                throw BizEx.of("更新订单学习状态失败")
            }
            // update class group status if all lessons completed
            if (classGroupMapper.completed(it.classGroupId!!) != 1) {
                throw BizEx.of("更新班级学习状态失败")
            }
        }

        // update class group completed lessons
        incs.forEach { (key, value) ->
            if (classGroupMapper.incConfirmedLessons(key, value) != 1) {
                throw BizEx.of("更新班级已完成课时数失败")
            }
        }
    }
}
